/**
 * @global THREE
 */

/**
 * 环境着色器
 * @global { ShaderMaterial }
 */
export const landscapeShaderMaterial = new THREE.ShaderMaterial({
  vertexShader: [
    'uniform float scale;',
    'uniform float time;',
    // 'varying float fog;',
    'varying vec3 vColor;',
    'void main() {',
    '	vColor = color;',
    '	vec4 p = modelViewMatrix * vec4(position, 1.0);',
    '	p.xyz += (0.1+0.00001*p.z*p.z)*vec3( sin(time+position.x+position.z), cos(time+position.y+position.z), sin(time+position.x+position.y+position.z) );',
    // '	fog = clamp(1.0 - pow(min(1.0, max(0.0, -(p.z+100.0) / 300.0)), 2.0), 0.0, 1.0);',
    '	gl_Position = projectionMatrix * p;',
    '	gl_PointSize = scale * 350.0 / length( p.xyz );',
    '}'
  ].join("\n"),
  fragmentShader: [
    'uniform sampler2D map;',
    // 'varying float fog;',
    'varying vec3 vColor;',
    'void main() {',
    '  gl_FragColor = vec4(vColor.xyz, 0.25 * pow(texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )).a, 2.0));',
    '}'
  ].join("\n"),
  vertexColors: true,
  blending: THREE.AdditiveBlending,
  uniforms: {
    time: {type: 'f', value: 0},
    scale: {type: 'f', value: 1},
    map: {type: 't', value: null}
  },
  transparent: true,
  depthWrite: false
});


/**
 * 素材着色器
 * @global { ShaderMaterial }
 */
export const canvasShaderMaterial = new THREE.ShaderMaterial({
  vertexShader: [
    'varying vec2 vUv;',
    'varying float fog;',
    'void main() {',
    '  vUv = uv;',
    '  vec4 p = modelViewMatrix * vec4(position, 1.0);',
    '  fog = pow(min(1.0, max(0.0, -(p.z+100.0) / 300.0)), 2.0);',
    '  gl_Position = projectionMatrix * p;',
    '}'
  ].join("\n"),

  fragmentShader: [
    'uniform sampler2D map;',
    'uniform vec3 color;',
    'varying vec2 vUv;',
    'varying float fog;',
    'void main() {',
    '  gl_FragColor = vec4(mix(color, vec3(0.4, 0.408, 0.365), fog), pow(texture2D(map, vUv).a, 2.0));',
    '}'
  ].join("\n"),

  uniforms: {
    map: {type: 't', value: null},
    color: {type: 'v3', value: null}
  },

  transparent: true,
  depthWrite: false
});

/**
 * 线条着色器
 * @global { ShaderMaterial }
 */
export const lineShaderMaterial = new THREE.ShaderMaterial({
  vertexShader: [
    'varying float fog;',
    'void main() {',
    '  vec4 p = modelViewMatrix * vec4(position, 1.0);',
    '  fog = pow(min(1.0, max(0.0, -(p.z+100.0) / 300.0)), 2.0);',
    '  gl_Position = projectionMatrix * p;',
    '}'
  ].join("\n"),
  fragmentShader: [
    'uniform vec3 color;',
    'varying float fog;',
    'void main() {',
    '  gl_FragColor = vec4(mix(color, vec3(0.4, 0.408, 0.365), fog), 1.0);',
    '}'
  ].join("\n"),
  uniforms: {
    color: {type: 'v3', value: null}
  },
  transparent: false,
  depthWrite: true
});

export const particleShader = {
  attributes: {
    position: {type: 'v3', value: []},
    scale: {type: 'f', value: []},
    color: {type: 'v3', value: []},
    // textureID: {type: 'f', value: []},
    uv: {type: 'v2', value: []}
  },
  uniforms: {},
  vertexShader: [
    // 'attribute float textureID;',
    'attribute float scale;',

    'varying vec3 vColor;',
    // 'varying float vTexID;',
    'varying vec2 vUv;',

    'void main() {',
    '	vColor = color;',
    // '	vTexID = textureID;',
    '	vUv = uv;',
    '	vec3 relativeVertexPosition = vec3(2.0 * uv - 1.0, 0.0);',
    '	vec3 v = position + 0.5 * scale * relativeVertexPosition;',
    '	gl_Position = projectionMatrix * modelViewMatrix * vec4( v, 1.0 );',
    '}'
  ].join('\n'),
  fragmentShader: [
    'varying vec3 vColor;',
    'varying float vTexID;',
    'varying vec2 vUv;',

    'uniform sampler2D t;',

    'void main() {',
    '	gl_FragColor = vec4(vColor, texture2D(t, vUv).a);',
    '}'
  ].join('\n'),

  vertexColors: THREE.FaceColors,
  side: THREE.DoubleSide,
  opacity: 1,
  transparent: true,
  depthWrite: false
};
